using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ICP_MS.Plugin.Tune;

public class DeadTimeExperiment
{
	public IsotopeRatio SelectedRatio = new IsotopeRatio();

	public List<AnalyteIsotope> SelectedIsotopes = new List<AnalyteIsotope>();

	public List<IsotopeRatio> Ratios = new List<IsotopeRatio>();

	public List<AnalyteIsotope> Isotopes = new List<AnalyteIsotope>();

	public double result11 = double.NegativeInfinity;

	public double result12 = double.NegativeInfinity;

	public double result21 = double.NegativeInfinity;

	public double result22 = double.NegativeInfinity;

	public List<double> result11List = new List<double>();

	public List<double> result12List = new List<double>();

	public int order = 0;

	public int sweeps = 10;

	public int dwelltime = 100;

	public double tao = 0.0;

	private Thread threadScan = null;

	private AutoResetEvent scanEvent = new AutoResetEvent(initialState: false);

	private List<double> massX = new List<double>();

	public bool bStableFunEnd = false;

	public bool TuneSucceed = false;

	private volatile bool bStable = false;

	public bool isRun { get; set; }

	public event EventHandler EventTuneFinish;

	public event EventHandler<MsgEventArgs> EventTuneMsg;

	public void InitIsotopes()
	{
		Isotopes.Clear();
		SelectedIsotopes.Clear();
		InitIsotope("164Er", "166Er");
		InitIsotope("113In", "115In");
		InitIsotope("174Hf", "180Hf");
		InitIsotope("235U", "238U");
		SelectedRatio = Ratios.First();
		SelectedIsotopes.AddRange(Isotopes.GetRange(0, 2));
	}

	private void InitIsotope(string symbol1, string symbol2)
	{
		IList<AnalyteIsotope> isos1 = DataBase.Instance.GetAnalyteIsotopesBySymbol(symbol1);
		if (isos1.Count > 0)
		{
			AnalyteIsotope selectIsotope2 = isos1.First();
			Isotopes.Add(selectIsotope2);
		}
		IList<AnalyteIsotope> isos2 = DataBase.Instance.GetAnalyteIsotopesBySymbol(symbol2);
		if (isos2.Count > 0)
		{
			AnalyteIsotope selectIsotope = isos2.First();
			Isotopes.Add(selectIsotope);
		}
		if (isos1.Count > 0 && isos2.Count > 0)
		{
			IsotopeRatio ratio = new IsotopeRatio
			{
				NumeratorId = isos1.First().id,
				NumeratorSym = isos1.First().symbol,
				DenominatorId = isos2.First().id,
				DenominatorSym = isos2.First().symbol,
				Name = isos1.First().symbol + "/" + isos2.First().symbol
			};
			Ratios.Add(ratio);
		}
	}

	public void StartScan()
	{
		Detector.finishReceive += Detector_finishReceive;
		isRun = true;
		threadScan = new Thread(ThreadScan);
		threadScan.Start();
	}

	private void ThreadScan()
	{
		bStable = true;
		bool bStableFuncEnd = true;
		Task.Factory.StartNew(delegate
		{
			bStableFuncEnd = false;
			while (bStable)
			{
				List<double> list = new List<double>();
				foreach (AnalyteIsotope current in SelectedIsotopes)
				{
					list.Add(current.mass);
				}
				List<int> list2 = new List<int>();
				for (int l = 0; l < list.Count; l++)
				{
					list2.Add(1);
				}
				Detector.Instance.SetMassAxis(list.ToArray());
				Detector.Instance.SendHopDatas(list.ToArray(), list2.ToArray(), true, false);
				if (!scanEvent.WaitOne(10000))
				{
					isRun = false;
					bStable = false;
					TuneMsg(Lang.Txt("CheckExperiment.Text9"));
					TuneFinish(success: false);
				}
				Thread.Sleep(5);
			}
			bStableFuncEnd = true;
		});
		int stabletime = 40;
		int lefttime = stabletime;
		while (isRun && lefttime-- > 0)
		{
			TuneMsg(string.Format(Lang.Txt("FormExperiment.Status.Delay.Text") + "{0}s", lefttime));
			Thread.Sleep(1000);
		}
		bStable = false;
		int WaitTime = 10;
		while (!bStableFuncEnd && isRun && WaitTime-- > 0)
		{
			Thread.Sleep(1000);
			TuneMsg($"等待稳定程序结束,剩余{WaitTime}s");
		}
		if (WaitTime <= 0)
		{
			isRun = false;
			Log.InsertLog("死时间校正", Lang.Txt("CheckExperiment.Text4"), "稳定程序出现出错", (Severity)3);
			TuneMsg("稳定程序出错");
			TuneFinish(success: false);
		}
		else
		{
			if (!isRun)
			{
				return;
			}
			Thread.Sleep(1000);
			massX.Clear();
			foreach (AnalyteIsotope isotope in SelectedIsotopes)
			{
				massX.Add(isotope.mass);
			}
			List<int> res = new List<int>();
			for (int j = 0; j < massX.Count; j++)
			{
				res.Add(1);
			}
			RFManager.rfs.dwell = dwelltime;
			Detector.Instance.msDetectorRF.SetDwell();
			result11List.Clear();
			result12List.Clear();
			for (int k = 0; k < 10; k++)
			{
				for (int i = 0; i < sweeps; i++)
				{
					if (i == 0)
					{
						Detector.Instance.SetMassAxis(massX.ToArray());
					}
					Detector.Instance.SendHopDatas(massX.ToArray(), res.ToArray(), true, false);
					if (!scanEvent.WaitOne(60000))
					{
						TuneMsg(Lang.Txt("CheckExperiment.Text5"));
						TuneFinish(success: false);
						return;
					}
					if (order == 1)
					{
						TuneMsg($"低浓度样品 正在扫描第{k + 1}次,重复次数第{i + 1}次");
					}
					else
					{
						TuneMsg($"高浓度样品 正在扫描第{k + 1}次,重复次数第{i + 1}次");
					}
				}
				double[] mass = Detector.msDetectorPara.MassAxis.ToArray();
				double[] intensity = Detector.msDetectorPara.IntesnsityPulse.ToArray();
				TuneMsg($"采集数据:第{k + 1}次 {intensity[0] / (double)sweeps} {intensity[1] / (double)sweeps} {intensity[0] / intensity[1]}");
				result11List.Add(intensity[0] / (double)sweeps);
				result12List.Add(intensity[1] / (double)sweeps);
			}
			if (order == 1)
			{
				result11 = result11List.Average();
				result12 = result12List.Average();
			}
			else
			{
				result21 = result11List.Average();
				result22 = result12List.Average();
			}
			TuneFinish(success: true);
		}
	}

	private void TuneFinish(bool success)
	{
		Detector.finishReceive -= Detector_finishReceive;
		TuneSucceed = success;
		if (this.EventTuneFinish != null)
		{
			this.EventTuneFinish(null, null);
		}
	}

	private void TuneMsg(string msg)
	{
		if (this.EventTuneMsg != null)
		{
			this.EventTuneMsg(null, new MsgEventArgs(msg));
		}
	}

	public void StopTune()
	{
		isRun = false;
		Detector.finishReceive -= Detector_finishReceive;
		if (threadScan != null && threadScan.IsAlive)
		{
			threadScan.Abort();
		}
		Detector.Instance.Stop();
		Detector.Instance.ExperimentState = -1;
	}

	private void Detector_finishReceive(object sender, EventArgs e)
	{
		scanEvent.Set();
	}

	public void ExperimentForStable()
	{
		Task.Factory.StartNew(delegate
		{
			bStableFunEnd = false;
			while (bStable)
			{
				List<double> list = new List<double>();
				foreach (AnalyteIsotope current in SelectedIsotopes)
				{
					list.Add(current.mass);
				}
				List<int> list2 = new List<int>();
				for (int i = 0; i < list.Count; i++)
				{
					list2.Add(1);
				}
				Detector.Instance.SetMassAxis(list.ToArray());
				Detector.Instance.SendHopDatas(list.ToArray(), list2.ToArray(), true, false);
				if (!scanEvent.WaitOne(10000))
				{
					isRun = false;
					bStable = false;
					TuneMsg(Lang.Txt("CheckExperiment.Text9"));
					TuneFinish(success: false);
				}
			}
			bStableFunEnd = true;
		});
	}

	public void CalculateResult()
	{
		double c = result22 * result11 - result21 * result12;
		double b = (result12 + result21) * result22 * result11 - result21 * result12 * (result11 + result22);
		if (b != 0.0)
		{
			tao = c / b;
		}
		if (tao < 0.0)
		{
			tao = 0.0;
		}
	}
}
